export class MapCreater{

    //地图生成的配置
    deep_num = 100;          //总深度
    deep_mountain = 60;      //以上化成山脉
    deep_forest = 10;        //以下变成森林

    /**
     * 地图生成器
     */
    game_map:Array<Point> = null;
    createMap(){
        //清空之前的地图
        this.game_map = [];
        //创建20*20个节点
        for(let i=0;i<400;i++) {
            let point = new Point();
            point.index = i;
            let random = Math.floor(Math.random() * this.deep_num);
            point.deep = random;
            this.game_map.push(point);
        }
        //生成河流
        for(let i=0;i<this.game_map.length;i++){
            if(this.game_map[i].deep>this.deep_num-2){ //98,99才能出水
                if(this.getAroundRiverNum(this.game_map[i].index)==0) {
                    this.game_map[i].type = 2;
                    this.createRiver(this.game_map[i].index, this.deep_num-1);
                }
            }
        }
        //生成山川
        this.createMountain();
        //生成森林
        this.createForest();

        //只需要type属性就足够了
        let types = [];
        this.game_map.forEach(point=>{
            types.push(point.type);
        });
        return types;
    }

    /**
     * 河流生成器
     */
    createRiver(index:number, deep:number){
        //先获取到周围上下左右4个点index
        let list_index = this.getAround(index);
        //根据index获取到4个point
        let list_point = new Array<Point>();
        for(let point of this.game_map){
            if(list_index.indexOf(point.index)!=-1){
                list_point.push(point);
            }
        }
        //找到比deep小最大的deep,同时周围不能有河
        let max = -1;
        for(let point of list_point){
            if(point.deep>=deep){
                continue;
            }
            //在这里判断，保留了支流的可能
            if(this.getAroundRiverNum(point.index)>=2){
                continue;
            }
            if(max<point.deep){
                max = point.deep;
            }
        }
        //如果max还是-1,就说明走到头了
        if(max == -1){
            return;
        }
        //把所有deep值等于max的point改成水,然后继续找下一个是水的地方
        let deep2 = --deep;
        for(let point of list_point){
            if(point.deep==max){
                //在这里再判断一次
                if(this.getAroundRiverNum(point.index)>=2){
                    continue;
                }
                point.deep = deep2;
                point.type = 2;
                this.createRiver(point.index,point.deep);
            }
        }
    }

    /**
     * 山川生成器
     */
    createMountain(){
        //找到所有要超过出山阈值的地图点
        let list = new Array();
        for(let point of this.game_map){
            if(point.deep>this.deep_mountain){
                list.push(point.index);
            }
        }
        //再把它们的上下左右也算进去,然后去重
        let list2 = new Array();
        for(let i of list){
            list2.push(i);
        }
        for(let i of list2){
            list.concat(this.getAround(i));
        }
        list = Array.from(new Set(list));
        //把包含地方全改成山
        for(let point of this.game_map){
            if(list.indexOf(point.index)!=-1){
                if(point.type==0){
                    point.type = 1;
                }
            }
        }
    }

    /**
     * 森林生成器
     */
    createForest(){
        //找到所有小于森林阈值的地图点
        let list = new Array();
        for(let point of this.game_map){
            if(point.deep<this.deep_forest){
                list.push(point.index);
            }
        }
        //再把它们的上下左右也算进去,然后去重
        let list2 = new Array();
        for(let i of list){
            list2.push(i);
        }
        for(let i of list2){
            list.concat(this.getAround(i));
        }
        list = Array.from(new Set(list));
        //把包含地方全改成森林
        for(let point of this.game_map){
            if(list.indexOf(point.index)!=-1){
                if(point.type==0){
                    point.type = 3;
                }
            }
        }
    }

    /**
     * 每个地图点的上下左右
     */
    getAround(index:number){
        let list = new Array();
        //上
        if(index+20<400){
            list.push(index+20);
        }
        //下
        if(index-20>0){
            list.push(index-20);
        }
        //左
        if(index%20!=0){
            list.push(index-1);
        }
        //右
        if((index+1)%20!=0) {
            list.push(index+1);
        }
        return list;
    }

    /**
     * 判断这个点周围有几个水
     */
    getAroundRiverNum(index:number){
        let list = this.getAround(index);
        let n = 0;
        if(list.length==0){
            return 0;
        }
        for(let j of list){
            if(this.game_map[j].type == 2){
                n++;
            }
        }
        return n;
    }
}

class Point{
    deep:number = 0;        //深度
    index:number = 0;       //索引
    type:number = 0;        //地形类型
}